# ultrasonic_device_controller.py

import serial
import threading
import time

class UltrasonicDeviceController:
    def __init__(self, port='/dev/ultrasonic', baudrate=9600):
        """
        初始化串口连接。
        
        :param port: 串口号，默认 '/dev/ttyUSB1'
        :param baudrate: 波特率，默认 9600
        """
        self.ser = serial.Serial(
            port=port,
            baudrate=baudrate,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_ODD,
            stopbits=serial.STOPBITS_ONE,
            timeout=1
        )
        self.timer = None
        self.lock = threading.Lock()
        self.running = False

    def send_raw_modbus_frame(self, hex_string):
        """
        发送原始 Modbus RTU 数据帧
        
        :param hex_string: 十六进制字符串，如 "01 05 00 01 FF 00 DD FA"
        """
        try:
            byte_data = bytes.fromhex(hex_string)
        except ValueError as e:
            raise ValueError(f"Invalid hex string: {hex_string}") from e

        with self.lock:
            print(f"[DEBUG] Sending raw frame: {byte_data.hex().upper()}")
            self.ser.write(byte_data)

    def start_ultrasonic(self, duration_seconds):
        """
        开启超声波，并在指定时间后自动关闭
        
        :param duration_seconds: 持续时间（秒）
        """
        if self.running:
            print("[INFO] Ultrasonic already running.")
            return "Already running."

        print("[INFO] Starting ultrasonic device.")
        self.send_raw_modbus_frame("01 05 00 01 FF 00 DD FA")
        self.running = True

        if self.timer:
            self.timer.cancel()

        self.timer = threading.Timer(duration_seconds, self.stop_ultrasonic)
        self.timer.start()
        print(f"[INFO] Will stop ultrasonic after {duration_seconds} seconds.")
        return f"Started for {duration_seconds} seconds."

    def stop_ultrasonic(self):
        """停止超声波"""
        if not self.running:
            print("[INFO] Ultrasonic is not running.")
            return "Not running."

        print("[INFO] Stopping ultrasonic device.")
        self.send_raw_modbus_frame("01 05 00 01 00 00 9C 0A")
        self.running = False
        return "Stopped successfully."

    def close(self):
        """关闭串口连接"""
        if self.timer:
            self.timer.cancel()
        self.ser.close()
        print("[INFO] Serial connection closed.")